
package jfilters.filters.color;

/*
    Copyright Janne Liljeblad 2008.

    This file is part of JFilters.

    JFilters is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    JFilters is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with JFilters.  If not, see <http://www.gnu.org/licenses/>.
*/

import jfilters.filters.SimpleLookUpFilter;
import jfilters.libmath.JFMath;

public class JFLevels extends SimpleLookUpFilter
{

	private double gamma;
	private int low_input;
	private int high_input;
	private int low_output;
	private int high_output;

	public JFLevels()
	{
		levels_init();
		initlookUp();
	}

	private void levels_init()
	{
		gamma = 1.0;
		low_input = 0;
		high_input = 255;
		low_output = 0;
		high_output = 255;
	}

	//--- range: 10.0 - 0.1, 10.0 means low gamma
	public void setGamma( double gamma_)
	{ 
		gamma = gamma_;
		initlookUp();
	}
	//--- range: 0 - 255
	public void setLowInput( int low_input_ )
	{ 
		low_input = low_input_; 
		initlookUp();
	}
	//--- range: 0 - 255
	public void setHighInput( int high_input_ )
	{ 
		high_input = high_input_;
		initlookUp();
	}
	//--- range: 0 - 255
	public void setLowOutput( int low_output_ )
	{ 
		low_output = low_output_;
		initlookUp();
	}
	//--- range: 0 - 255
	public void setHighOutput( int high_output_ )
	{ 
		high_output = high_output_;
		initlookUp();
	}

	public double lut_func( double value )
	{
		double inten = value;
		
		/*  determine input intensity  */
		if ( high_input != low_input )
		{
			inten = ((double) (255.0 * inten - low_input ) /
				(double) (high_input - low_input ));
		}
		else
		{
			inten = (double) (255.0 * inten - low_input );
		}
			
		if ( gamma != 0.0)
		{
			if (inten >= 0.0)
				inten =  Math.pow( inten, (1.0 / gamma ));
			else
				inten = - Math.pow(-inten, (1.0 / gamma ));
		}

		/*  determine the output intensity  */
		if ( high_output >= low_output )
			inten = (double) ( inten * ( high_output - low_output ) + low_output );
		else if ( high_output < low_output )
			inten = ( double ) ( low_output - inten * ( low_output - high_output ) );
			
		inten /= 255.0;
		
		return JFMath.CLAMP( inten, 0.0, 1.0 );
	}

}//end class
